export default {
	// 开启命名空间
	// vuex中的store分模块管理，需要在store的index.js中
	// 咱这里index.js是store.js
	// 引入各个模块，为了解决不同模块命名冲突的问题，
	// 将不同模块的namespaced:true，之后在不同页面中
	// 引入getter、actions、mutations时，需要加上所属的模块名
	namespaced: true,
	// 箭头函数返回对象字面量时 必须加一个()包裹
	state: () => ({
		// 购物车的数组，用来存储购物车中每个商品的信息对象
		// 每个商品的信息对象 都包含如下的6个属性
		// { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }
		// cart: []
		cart: JSON.parse(uni.getStorageSync('cart') || '[]')
	}),
	// statez中的数据只能被matations修改
	mutations:{
		addToCart(state, goods) {
			
			// find() 方法为数组中的每个元素都调用一次函数执行：
			// 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素，之后的值不会再调用执行函数。
			// 如果没有符合条件的元素返回 undefined
			// find() 对于空数组，函数是不会执行的。
			// find() 并没有改变数组的原始值。
			const findResult = state.cart.find(x => x.goods_id === goods.goods_id)
			// console.log(findResult);
			if(!findResult){
				// 在cart数组中找不到该商品 那就添加该商品
				state.cart.push(goods)
			}else{
				// 否则就是存在相同商品 则数量加1
				findResult.goods_count++
			}
			// console.log(state.cart);
			// 在对cart数组操作结束以后 将cart数组中数据持久化到本地
			// 使用commit方法去调用m_cart模块下的saveToStorage方法
			this.commit('m_cart/saveToStorage')
		},
		// 将购物车里的商品持久化保存到本地
		saveToStorage(state){
			// 以字符串形式保存到本地
			uni.setStorageSync('cart',JSON.stringify(state.cart))
		},
		// 更新购物车里的商品的勾选状态
		updateGoodsState(state,goods){
			const findResult = state.cart.find( x => x.goods_id === goods.goods_id)
			
			if(findResult){
				findResult.goods_state = goods.goods_state
				this.commit('m_cart/saveToStorage')
			}
		},
		// 更新购物车里的商品数量
		updateGoodsCount(state,goods){
			const findResult = state.cart.find( x => x.goods_id === goods.goods_id)
			
			if(findResult){
				findResult.goods_count = goods.goods_count
				this.commit('m_cart/saveToStorage')
			}
		},
		// 根据商品id删除购物车里对应的商品
		romoveGoodsById(state,goods_id){
			// 过滤所有不是要删除的商品 将其重新赋值给cart
			// 就能实现删除对应id的商品
			
			// Array中filter() 方法创建一个新的数组，
			// 新数组中的元素是通过检查指定数组中符合条件的所有元素。
			// 注意： filter() 不会对空数组进行检测。
			// 注意： filter() 不会改变原始数组。
			// 这里我们不能使用find 因为它找到的元素返回是对象 而我们需要的是数组
			state.cart = state.cart.filter( x => x.goods_id !== goods_id)
			
			this.commit('m_cart/saveToStorage')
		},
		// 更新购物车中所有商品的勾选状态
		updateAllGoodsState(state,newState){
			state.cart.forEach(x => x.goods_state = newState)
			this.commit('m_cart/saveToStorage')
		}
	},
	// 它就是一个计算属性 
	// 计算属性一般就是用来通过其他的数据算出一个新数据，
	// 而且它有一个好处就是，它把新的数据缓存下来了，
	// 当其他的依赖数据没有发生改变，
	// 它调用的是缓存的数据，这就极大的提高了我们程序的性能。
	// 而如果写在methods里，数据根本没有缓存的概念，
	// 所以每次都会重新计算。这也是为什么这里我们没用methods的原因
	getters:{
		// 定义一个计算购物车微标数量的属性 它是所有的商品的总数量
		// 它是根据goods_count来计算的
		total(state){
			// let c = 0
			// state.cart.forEach(x => {
			// 	c += x.goods_count
			// })
			// return c
			// 使用数组的reduce方法改造当前代码
			return state.cart.reduce((total,item) => total += item.goods_count,0)
		},
		
		// 我们通过比较商品的状态和商品的数量个数来实现全选和反选 
		
		// 勾选商品的总数量(它是根据goods_state和goods_count来计算的)
		checkCounts(state){
			// 先使用filter方法过滤出一个关于goods_state的新数组出来
			// 再使用reduce方法，将已勾选的商品总数量进行累加
			// reduce方法的返回值就是已勾选的商品总数量
			// reduce() 方法接收一个函数作为累加器，数组中的每个值（从左到右）开始缩减，最终计算为一个值。
			// array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
			// total	必需。初始值, 或者计算结束后的返回值。
			// currentValue	必需。当前元素
			// currentIndex	可选。当前元素的索引
			// arr	可选。当前元素所属的数组对象。
			return state.cart.filter(x => x.goods_state).reduce((total,item) => total += item.goods_count,0)
		},
		// 已勾选商品的总价格
		checkedGoodsAmount(state){
			return state.cart.filter(x => x.goods_state).reduce((total,item) => total += item.goods_count * item.goods_price,0).toFixed(2)
		}
		
	}
}